import { OptionsApi } from "@/service/options-api"
import { ProjectService } from "@/service/projects-api"
import { Backups } from "@/utils/backups"
import { ComUtils } from "@/utils/Com"
import { createSignal, For, onMount, Show } from "solid-js"
import MyButton from "../com/MyButton"
import { MessageBox } from "@/utils/messagebox"
import { BACKUP_LIST, BACKUP_NAME } from "@/utils/backups/conf"
import { BrowserUtils } from "@/us/browser"

export default function () {

    const [form, setForm] = createSignal<OptionsInfo>({
        backups: {
            auto: false,
            autoTime: 1000 * 60 * 1,
            type: "aliyundrive" as BackupsType
        },
        autoUpdateScripts: true,
    })
    const [manualBackupLoading, setManualBackupLoading] = createSignal(false)
    const [cloudRestoreLoading, setCloudRestoreLoading] = createSignal(false)
    const [backupsAuth, setBackupsAuth] = createSignal(false)
    const [backupsAuthLoading, setBackupsAuthLoading] = createSignal(false)
    const [cancelAuthLoading, setCancelAuthLoading] = createSignal(false)

    const [manualRefreshScriptsLoading, setManualRefreshScriptsLoading] = createSignal(false)

    const setFormValue = async (k: string, val: any) => {
        let obj = { ...form() }
        let keys = k.split('.')
        if (keys.length > 1) {
            const target = Reflect.get(obj, keys[0])
            Reflect.set(target, keys[1], val)
        } else {
            Reflect.set(obj, k, val)
        }
        setForm(obj)
        OptionsApi.save(obj)

        if (k === 'backups.type') {
            await Backups.init()
            loadData(false)
        }
    }

    const authBackups = async () => {
        if (backupsAuthLoading()) {
            return
        }
        setBackupsAuthLoading(true)
        Backups.auth().then(() => {
            setBackupsAuthLoading(false)
            setBackupsAuth(true)
        }).catch((err) => {
            setBackupsAuthLoading(false)
            console.log(err)
            MessageBox.error(ComUtils.tr('auth_fail'))
        })
    }

    const cancelAuth = async () => {
        try {
            setCancelAuthLoading(true)
            await Backups.cancelAuth()
            setBackupsAuth(false)
            setCancelAuthLoading(false)
        } catch (error) {
            setCancelAuthLoading(false)
            MessageBox.error(ComUtils.tr('cancel_auth_fail'))
            console.log(error)
        }
    }

    const manualBackup = async () => {
        if (manualBackupLoading()) {
            return
        }
        setManualBackupLoading(true)
        try {
            await Backups.save()
            MessageBox.success(ComUtils.tr('backup_success'))
        } catch (error) {
            MessageBox.error(ComUtils.tr('backup_fail'))
            console.log(error)
        }
        setManualBackupLoading(false)
    }

    const cloudRestore = async () => {
        if (cloudRestoreLoading()) {
            return
        }
        setCloudRestoreLoading(true)
        try {
            const res = await Backups.load()
            if (!res) {
                MessageBox.error(ComUtils.tr('restore_fail_empty'))
                setCloudRestoreLoading(false)
                return
            }
            setForm({ ...res.conf })
            MessageBox.success(ComUtils.tr('restore_success'))
        } catch (error) {
            MessageBox.error(ComUtils.tr('restore_fail'))
            console.log(error)
        }
        setCloudRestoreLoading(false)
    }

    const manualRefreshScripts = ()=>{
        setManualRefreshScriptsLoading(true)
        ComUtils.callChromeMethod('checkAndUpdateScripts', {}).then(() => {
            MessageBox.success(ComUtils.tr('refresh_success'))
        }).catch(() => {
            MessageBox.error(ComUtils.tr('refresh_fail'))
        }).finally(() => {
            setManualRefreshScriptsLoading(false)
        })
    }

    const loadData = async (forceConf = true) => {
        const backupsAuthRes = await Backups.isAuth()
        setBackupsAuth(backupsAuthRes)
        if (forceConf) {
            const conf = await OptionsApi.getConfig()
            if (conf) {
                setForm(conf)
            }
        }
    }

    const localBackups = async () => {
        if (manualBackupLoading()) {
            return
        }
        setManualBackupLoading(true)
        try {
            const blob = await Backups.packBackup()
            ComUtils.downloadFile(URL.createObjectURL(blob), ComUtils.tr('app_name') + '-' + BACKUP_NAME)
            MessageBox.success(ComUtils.tr('backup_success'))
        } catch (error) {
            console.log(error)
            MessageBox.error(ComUtils.tr('backup_fail'))
        }
        setManualBackupLoading(false)
    }

    const localRestore = async () => {
        if (cloudRestoreLoading()) {
            return
        }
        setCloudRestoreLoading(true)
        try {
            const file = await BrowserUtils.openFile() as File
            if (!file) {
                return
            }
            const res = await Backups.unpackBackup(file)
            setForm({ ...res.conf })
            await ProjectService.saveAll(res.projects)
            await OptionsApi.save(res.conf)
            MessageBox.success(ComUtils.tr('restore_success'))
        } catch (error) {
            MessageBox.error(ComUtils.tr('restore_fail'))
        }
        setCloudRestoreLoading(false)
    }

    onMount(() => {
        loadData()
    })

    const LocalBackup = <div class="flex items-center gap-4">
        <MyButton text={ComUtils.tr('local_backups')} loading={manualBackupLoading} onclick={localBackups} />
        <MyButton text={ComUtils.tr('local_restore')} loading={cloudRestoreLoading} onclick={localRestore} />
    </div>

    return <div class="flex flex-col gap-6 px-6 py-5 mx-auto">
        <div class=" bg-[#222222] border border-[#3a3a3a] rounded p-4">
            <h4 class="flex items-center justify-between gap-2 mb-5">
                <span>
                    {ComUtils.tr('backups')}
                </span>
                <select value={form().backups.type} onchange={(e) => setFormValue('backups.type', e.target.value as any)}>
                    <For each={BACKUP_LIST}>
                        {
                            val => <option value={val}>
                                {ComUtils.tr('backup_' + val)}
                            </option>
                        }
                    </For>
                </select>
            </h4>
            <Show when={form().backups.type !== 'local'} fallback={LocalBackup}>
                <Show when={backupsAuth()} fallback={
                    <>
                        <MyButton class="btn" text={ComUtils.tr('auth')} loading={backupsAuthLoading} onclick={authBackups} />
                    </>
                }>
                    <div class="flex flex-col gap-3 items-start">
                        <label class="text-[#999] align-middle">
                            <input type="checkbox" checked={form().backups.auto} onchange={(e) => setFormValue('backups.auto', e.target.checked)} />
                            <span class=" ml-1">
                                {ComUtils.tr('auto_backup')}
                            </span>
                            <Show when={form().backups.auto && Backups.state.lastBackupTime > 0}>
                                <span class="ml-1 text-xs text-[#8a8a8a]">
                                    {ComUtils.tr('auto_backup_last_time')}
                                    &nbsp;
                                    <i>
                                        {ComUtils.formatDate(Backups.state.lastBackupTime)}
                                    </i>
                                </span>
                            </Show>
                        </label>
                        <div class="flex items-center gap-4">
                            <MyButton text={ComUtils.tr('cancel_auth')} loading={cancelAuthLoading} onclick={cancelAuth} />
                            <MyButton text={ComUtils.tr('manual_backup')} loading={manualBackupLoading} onclick={manualBackup} />
                            <MyButton text={ComUtils.tr('cloud_restore')} loading={cloudRestoreLoading} onclick={cloudRestore} />
                        </div>
                    </div>
                </Show>
            </Show>
            <h4 class="flex items-center justify-between gap-2 mt-5">
                <span>
                    {ComUtils.tr('auto_update_scripts')}
                </span>
                <MyButton text={ComUtils.tr('manual_refresh_scripts')} loading={manualRefreshScriptsLoading} onclick={manualRefreshScripts} />
            </h4>
            <p>
                <label class="text-[#999] align-middle">
                    <input type="checkbox" checked={form().autoUpdateScripts} onchange={(e) => setFormValue('autoUpdateScripts', e.target.checked)} />
                    <span class=" ml-1">
                        {ComUtils.tr('auto_update_scripts_desc')}
                    </span>
                </label>
            </p>
        </div>
        <div class=" flex flex-col justify-center items-center">
            <img class="w-40" src="/settings/logo.png" alt="logo" />
            <p class=" w-ful text-center text-[#6d6b6b] text-sm">
                {ComUtils.tr('app_name')}
            </p>
        </div>
    </div>
}